<?php 
/******* 
 * Stephen Hitchner (steve@number41media.com) 
 * db_mysql.class 
 *
 * Created:  [03/2002] 
 * Revised:  [01/2005]
 *
 * Updated for PHP5
 * Requires database.inc
 *
 */ 

/******************************************************* 
 * Database Class 
 *******************************************************/ 
Class DB_Mysql extends DB_Abstract { 

        //*****************************************************
        // Private Connection Function Constructor, Destuctor
        function __construct($info) {
		parent::__construct($info);
                self::open();
        }
	//-----------------------------------------------------
        function __destruct() {
                self::close();
		parent::__destruct();
        }
	//-----------------------------------------------------
	function __toString() {
		return print_r( $this, true );
	}
   
  	//***************************************************** 
  	// Private Functions 
	//-----------------------------------------------------
	protected function open() { 
		if ( is_array($this->_info) ) {
			if ( $this->_info['persistant'] == true ) {
				 $connect_funct = 'mysql_pconnect';
			} else {
				 $connect_funct = 'mysql_connect';
			}

			if ( $this->_dbi = @$connect_funct($this->_info['host'], $this->_info['user'], $this->_info['password']) ) {
				$this->_connected = true;
				Log::info("[open] Connected to server: ". $this->_info['host']);
				self::selectDb();
				return true;
			} else {
				Log::fatal("[open] Could not connect to server: " . 
						$this->_info['host']);
				return false;
			}
		} else {
			Log::error("[open] No Database Info");
			return false;
		}
	}
	//-----------------------------------------------------
	protected function close() { 
    		if ( $this->_connected ) { 
      			@mysql_close($this->_dbi); 
			$this->_connected = false;
      			return true; 
    		} 
    		Log::fatal("[close] Not connected to database server"); 
		return false; 
  	} 
	//-----------------------------------------------------
	private function selectDb() { 
    		if ( $this->_connected ) { 
      			if ( @mysql_select_db($this->_info['database'], $this->_dbi) ) { 
				return true; 
      			} else { 
				Log::error("[select_db] Could not select database: ". $this->_info['database']); 
				return false; 
      			} 
    		} 
    		Log::fatal("[select_db] Not connected to database server"); 
    		return false; 
  	} 

  	//***************************************************** 
  	// Public Query Functions 
	//-----------------------------------------------------
	public function select($query) { 
		if ( $this->_connected ) { 
			if ( $results = @mysql_query($query, $this->_dbi) ) { 
				Log::debug("SELECT: $query"); 
				// Returns a results object 
				return new Result_Mysql($results); 
      			}
			$error = "[select] Error with select: $query" .
					mysql_error($this->_dbi);
      			Log::error($error);
      			return @new Result_Mysql(NULL); 
    		} 
    		Log::fatal("[select] Not connected to database server"); 
    		return @new Results(NULL); 
  	} 
	//-----------------------------------------------------
  	public function insert($query) { 
		if ( $this->_connected ) { 
			if ( $results = @mysql_query($query, $this->_dbi) ) { 
				Log::debug("INSERT: $query"); 
				return @mysql_insert_id($this->_dbi); 
      			} 
			$error = "[insert] Error with insert: $query" . mysql_error($this->_dbi);
			Log::error($error);
      			return false;			 
		} 
		Log::fatal("[insert] Not connected to database server"); 
		return false; 
	} 
	//-----------------------------------------------------
	public function update($query) { 
		if ( $this->_connected ) { 
			if ( $results = @mysql_query($query, $this->_dbi) ) { 
				Log::debug("UPDATE: $query"); 
				return @mysql_affected_rows($this->_dbi); 
			} 
			$error = "[update] Error with update: $query" . mysql_error($this->_dbi);
			Log::error($error);
			return false; 
		} 
		Log::fatal("[update] Not connected to database server"); 
		return false; 
	} 

	//***************************************************** 
	// Public Transaction Functions 
	//-----------------------------------------------------
	public function begin() {
		if ( $this->_connected ) { 
			if ( @mysql_query("SET autocommit=0", $this->_dbi) &&
					 @mysql_query("BEGIN WORK", $this->_dbi) ) {
				Log::debug("BEGIN WORK"); 
				return true;
			}
			Log::error("[begin] Unable to begin. Server may not support transactions"); 
			return false; 
		}
		Log::fatal("[begin] Not connected to database server"); 
		return false; 
	}
	//-----------------------------------------------------
	public function rollback() {
		if ( $this->_connected ) { 
			if ( @mysql_query("ROLLBACK", $this->_dbi) ) {
				@mysql_query("SET autocommit=1", $this->_dbi);
				Log::debug("ROLLBACK"); 
				return true;
			}
			Log::error("[rollback] Unable to rollback. Server may not support transactions"); 
			return false; 
		}
		Log::fatal("[rollback] Not connected to database server"); 
		return false; 
	}
	//-----------------------------------------------------
	public function commit() {
		if ( $this->_connected ) { 
			if ( @mysql_query("COMMIT", $this->_dbi) ) {
				@mysql_query("SET autocommit=1", $this->_dbi);
				Log::debug("COMMIT"); 
				return true;
			}
			Log::error("[commit] Unable to commit. Server may not support transactions"); 
			return false; 
		}
		Log::fatal("[commit] Not connected to database server"); 
		return false; 
	}		
	//-----------------------------------------------------
	public function lock($string) {
		if ( $this->_connected ) { 
			if ( @mysql_query("LOCK TABLES $string", $this->_dbi) ) {
				return true;
			}
			Log::error("[lock] Unable to lock tables: $string"); 
			return false; 
		}
		Log::fatal("[lock] Not connected to database server"); 
		return false; 
	}		
	//-----------------------------------------------------
	public function unlock() {
		if ( $this->_connected ) { 
			if ( @mysql_query("UNLOCK TABLES", $this->_dbi) ) {
				return true;
			}
			Log::error("[unlock] Unable to unlock tables"); 
			return false; 
		}
		Log::fatal("[unlock] Not connected to database server"); 
		return false; 
	}		
} 
 
/******************************************************* 
 * Results Class 
 *******************************************************/ 
Class Result_Mysql extends Result { 
	private $_currentRow;
	private $_index;
	
	//*****************************************************
	// Constructor and Database Operations Functions
	//-----------------------------------------------------
	function __construct($results) {
		parent::__construct( $results );
		$this->_index = 0;
	}
	//-----------------------------------------------------
	function __destruct() {
		self::free();
		parent::__destruct();
	}
	//----------------------------------------------------- 
	function __toString() {
		return print_r( $this, true );
	}

	//****************************************************
	// Interation
	//----------------------------------------------------
	public function rewind() {
		self::seek(0);
		$this->_index = 0;
		self::next();
	}
	//-----------------------------------------------------
	public function current() {
		return $this->_currentRow;
	}
	//-----------------------------------------------------
	public function key() {
		return $this>_index;
	}
	//-----------------------------------------------------
	public function next() {
		$this->_currentRow = self::getRowAssoc();
		$this->_index++;
	}
	//-----------------------------------------------------
	public function valid() {
		return $this->_currentRow != false;
	}

	//***************************************************** 
	// Public Functions 
	//----------------------------------------------------- 
	public function getAllRows() {
		$arr = Array();
		$row = self::getRowAssoc();
		while ( $row = self::getRowAssoc() ) {
			$arr[] = $row;
		}
		return $arr;
	}
	//----------------------------------------------------- 
	public function getRow() { 
		if ( $row = @mysql_fetch_array($this->_results, MYSQL_NUM) ) { 
			return $row; 
		} 
		Log::error("[getRow] Error getting row"); 
		return false;
	} 
	//----------------------------------------------------- 
	public function getRowAssoc() { 
		if ( $row = @mysql_fetch_array($this->_results, MYSQL_ASSOC) ) { 
			return $row; 
		} 
		Log::error("[getRowAssoc] Error getting row"); 
		return false;
	} 
	//----------------------------------------------------- 
	public function getField($i) { 
		if ( $field = @mysql_fetch_field($this->_results, $i) ) { 
			return $field; 
		} 
		Log::error("[get_field] Error getting field object"); 
		return NULL; 
	} 
	//----------------------------------------------------- 
	public function getFields() { 
		$fields = Array(); 
		for($i=0; $i<self::get_numfields($this->_results); $i++) { 
			$fields[$i] = @mysql_field_name($this->_results, $i); 
		} 
		if ( count($fields) > 0 ) { 
			return $fields; 
		} 
		Log::error("[get_fields] Error getting fields array"); 
		return Array(); 
  	} 
	//----------------------------------------------------- 
	public function getNumFields() { 
		if ( $num = @mysql_num_fields($this->_results) ) { 
			return $num; 
		} 
		Log::error("[get_numfields] Error getting number of fields");	 
		return 0; 
	} 
	//----------------------------------------------------- 
	public function free() {
		@mysql_free_result($this->_results);
		unset($this);
	}
	//-----------------------------------------------------
	public function seek($i) {
		$result = @mysql_data_seek( $this->_results, $i );
		if ( !$result ) {
			return @mysql_data_seek( $this->_results, 0 );
		}
		return $result;
	}
}
?>
